/**
 * 
 */
package pers.vic.test.quartz.util;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import pers.vic.test.quartz.model.QuartzCustomerJob;

/**
 *  @description: 
 *  @author Vic.xu
 *  @date: 2020年8月28日下午5:04:40
 */
@Component
public class QuartzManager {
    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    
    private static Logger log = LoggerFactory.getLogger(QuartzManager.class);

    /**
     * 添加任务，使用任务组名（不存在就用默认的），触发器名，触发器组名
     * 并启动
     * @param info
     */
    @SuppressWarnings("unchecked")
	public void addJob(QuartzCustomerJob info) {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();

            JobKey jobKey = JobKey.jobKey(info.getCode(), info.getGroup());
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (null != jobDetail) {
                log.info("{}， {} 定时任务已经存在", info.getCode(), info.getGroup());
                return;
            }

            JobDataMap map = new JobDataMap();
            map.put("taskData", "测试的存放的数据");

            // JobDetail 是具体Job实例
            jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(info.getClazz()))
                    .withIdentity(info.getCode(),info.getGroup())
                    .usingJobData(map)
                    .build();

            // 基于表达式构建触发器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(info.getCron());
            // CronTrigger表达式触发器 继承于Trigger
            // TriggerBuilder 用于构建触发器实例
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(info.getCode()+"_trigger", info.getGroup())
                    .withSchedule(cronScheduleBuilder).build();

            scheduler.scheduleJob(jobDetail, cronTrigger);

            //启动
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }
        } catch (SchedulerException | ClassNotFoundException e) {
            log.error("添加任务失败",e);
        }
    }

    /**
     * 暂停任务
     * @param info
     */
    public void pauseJob(QuartzCustomerJob info) {
        try{
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            JobKey jobKey = JobKey.jobKey(info.getCode(), info.getGroup());
            scheduler.pauseJob(jobKey);
            log.info("=========================pause job: {} success========================", info.getCode());
        }catch (Exception e){
            log.error("",e);
        }
    }

    /**
     * 恢复任务
     * @param info
     */
    public void resumeJob(QuartzCustomerJob info) {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            JobKey jobKey = JobKey.jobKey(info.getCode(), info.getGroup());
            scheduler.resumeJob(jobKey);
            log.info("=========================resume job: {} success========================", info.getCode());
        }catch (Exception e){
            log.error("",e);
        }
    }

    /**
     * 删除任务，在业务逻辑中需要更新库表的信息
     * @param info
     * @return
     */
    public boolean removeJob(QuartzCustomerJob info) {
        boolean result = true;
        try {

            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            JobKey jobKey = JobKey.jobKey(info.getCode(), info.getGroup());
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (null != jobDetail) {
                result =  scheduler.deleteJob(jobKey);
            }
            log.info("=========================remove job: {} {}========================", info.getCode(), result);
        }catch (Exception e){
            log.error("",e);
            result=false;
        }
        return result;
    }

    /**
     * 修改定时任务的时间
     * @param info
     * @return
     */
    public boolean modifyJobTime(QuartzCustomerJob info){
        boolean result = true;
        try{
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(info.getCode() + "_trigger", info.getGroup());
            CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);

            String oldTime = trigger.getCronExpression();
            if (!StringUtils.equalsIgnoreCase(oldTime, info.getCron())) {
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(info.getCron());
                CronTrigger ct = TriggerBuilder.newTrigger().withIdentity(info.getCode()+ RandomStringUtils.randomAlphabetic(6) + "_trigger",  info.getGroup())
                        .withSchedule(cronScheduleBuilder)
                        .build();

                scheduler.rescheduleJob(triggerKey, ct);
                scheduler.resumeTrigger(triggerKey);
            }

        }catch (Exception e){
            log.error("", e);
            result=false;
        }
        return result;
    }

    /**
     * 启动所有定时任务
     */
    public void startJobs() {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            scheduler.start();
        } catch (SchedulerException e) {
            log.error("",e);
        }
    }
}

